home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 1997 #1 / Amiga Plus CD - 1997 - No. 01.iso / pd / programmierung / proasm / routines / gtfsupport.r < prev    next >
Text File  |  1993-10-25  |  14KB  |  850 lines

  1.  
  2. ;---;  gtfsupport.r  ;---------------------------------------------------------
  3. *
  4. *    ****    VARIOUS GTFACE SUPPORT ROUTINES    ****
  5. *
  6. *    Author        Stefan Walter
  7. *    Version        1.03
  8. *    Last Revision    23.10.93
  9. *    Notes        demands calls with CALL_ macro
  10. *    Identifier    gfs_defined
  11. *    Prefix        gfs_    (GTFace support)
  12. *                 ¯ ¯    ¯
  13. *    Functions    AllocLVNode, AllocLVNodeRaw, FreeLVNode
  14. *            AddHeadLVNode, AddTailLVNode, RemHeadLVNode
  15. *            RemTailLVNode, RemoveLVNode, FreeLVList.
  16. *
  17. *            SetGadgetTag,SetLVLabels,RemoveLVLabels,
  18. *            ChangeLVLabels, SetCYActive, GetLVLabels
  19. *            ActivateGadget, OnMenu, OffMenu, FindLVNode,
  20. *            FindLVNodeMsg.
  21. *
  22. *            StringHistoryHookFunction
  23. *
  24. ;------------------------------------------------------------------------------
  25.  
  26. ;------------------
  27.     ifnd    gfs_defined
  28. gfs_defined    =1
  29.  
  30. ;------------------
  31. ; Some macros.
  32. ;
  33.     include    basicmac.r
  34.     include    tasktricks.r
  35.  
  36.  
  37.  
  38.  
  39. ;------------------------------------------------------------------------------
  40. *
  41. * AllocLVNodeRaw    Allocate a listview node due to a string generated
  42. *            with RawDoFmt(). The string is copied.
  43. *
  44. * INPUT:    a0    Format string.
  45. *        a1    Raw data.
  46. *        d0    Number of bytes to add after node structure.
  47. *
  48. * RESULT:    d0    Node or 0.
  49. *        a0    Node or 0.
  50. *        ccr    On d0.
  51. *
  52. ;------------------------------------------------------------------------------
  53.  
  54. ;------------------
  55.     IFD    xxx_AllocLVNodeRaw
  56. AllocLVNodeRaw:
  57.  
  58. ;------------------
  59. ; Start.
  60. ;
  61. \start:    movem.l    d1-d7/a1-a6,-(sp)
  62.     move.l    d0,d5
  63.     move.l    a0,a3
  64.     move.l    a1,a4
  65.     DoRawCnt_
  66.  
  67.     add.l    d5,d0
  68.     moveq    #14,d1
  69.     add.l    d1,d0    
  70.  
  71.     moveq    #1,d1            ;even VMem allowed!
  72.     swap    d1            ;clear!
  73.     move.l    4.w,a6
  74.     jsr    -198(a6)        ;AllocMem()
  75.     tst.l    d0
  76.     beq.s    \done
  77.  
  78.     move.l    d0,a2
  79.     move.l    a3,a0
  80.     move.l    a4,a1
  81.     lea    14(a2,d5.l),a3
  82.     move.l    a3,10(a2)
  83.     
  84.     DoRaw_
  85.  
  86. \done:    move.l    d0,a0
  87.     movem.l    (sp)+,d1-d7/a1-a6
  88.     rts
  89.  
  90.     ENDIF
  91. ;------------------
  92.  
  93.  
  94.  
  95.  
  96. ;------------------------------------------------------------------------------
  97. *
  98. * AllocLVNode    Allocate a listview node. The node will contain a selected
  99. *        number of bytes after the node structure and a string that is
  100. *        copied.
  101. *
  102. * INPUT:    a0    String (will appear in the listview gadget).
  103. *        d0    Number of bytes to add after node structure.
  104. *
  105. * RESULT:    d0    Node or 0.
  106. *        a0    Node or 0
  107. *        ccr    On d0.
  108. *
  109. ;------------------------------------------------------------------------------
  110.  
  111. ;------------------
  112.     IFD    xxx_AllocLVNode
  113. AllocLVNode:
  114.  
  115. ;------------------
  116. ; Start.
  117. ;
  118. \start:    movem.l    d1-d7/a1-a6,-(sp)
  119.     move.l    a0,a2
  120.     move.l    d0,d7
  121.     moveq    #14,d0            ;LN_SIZEOF
  122.     add.l    d7,d0            ;+ desired number of bytes
  123. \loop:    addq.l    #1,d0            ;+ string size
  124.     tst.b    (a0)+
  125.     bne.s    \loop
  126.  
  127.     moveq    #1,d1            ;even VMem allowed!
  128.     swap    d1            ;clear!
  129.     move.l    4.w,a6
  130.     jsr    -198(a6)        ;AllocMem()
  131.     tst.l    d0
  132.     beq.s    \done
  133.  
  134.     move.l    d0,a0
  135.     lea    14(a0,d7.l),a1
  136.     move.l    a1,10(a0)
  137. \loop2:    move.b    (a2)+,(a1)+        ;copy string...
  138.     bne.s    \loop2
  139.     tst.l    d0
  140.  
  141. \done:    move.l    d0,a0
  142.     movem.l    (sp)+,d1-d7/a1-a6
  143.     rts
  144.  
  145.     ENDIF
  146. ;------------------
  147.  
  148.  
  149.  
  150.  
  151. ;------------------------------------------------------------------------------
  152. *
  153. * FreeLVList    Remove the entier listview list and free all nodes.
  154. *
  155. * INPUT:    a0    List.
  156. *        a2    WindowKey.
  157. *        a3    Gadget.
  158. *
  159. ;------------------------------------------------------------------------------
  160.  
  161. ;------------------
  162.     IFD    xxx_FreeLVList
  163. FreeLVList:
  164.  
  165. ;------------------
  166. ; Start.
  167. ;
  168. \start:    movem.l    d0-a6,-(sp)
  169.     move.l    a0,a4
  170.     move.l    a3,a0
  171.     CALL_    RemoveLVLabels
  172.     move.l    4.w,a6
  173. \loop:    move.l    a4,a0
  174.     jsr    -258(a6)        ;RemHead()
  175.     tst.l    d0
  176.     beq.s    \done
  177.     move.l    d0,a0
  178.     CALL_    FreeLVNode
  179.     bra.s    \loop
  180. \done:    movem.l    (sp)+,d0-a6
  181.     rts
  182.  
  183.     ENDIF
  184. ;------------------
  185.  
  186.  
  187.  
  188.  
  189. ;------------------------------------------------------------------------------
  190. *
  191. * FreeLVNode    Free a previously generated listview node.
  192. *
  193. * INPUT:    a0    Node.
  194. *
  195. ;------------------------------------------------------------------------------
  196.  
  197. ;------------------
  198.     IFD    xxx_FreeLVNode
  199. FreeLVNode:
  200.  
  201. ;------------------
  202. ; Start.
  203. ;
  204. \start:    movem.l    d0-a6,-(sp)
  205.     move.l    10(a0),a2
  206. \loop:    tst.b    (a2)+
  207.     bne.s    \loop
  208.     move.l    a2,d0
  209.     sub.l    a0,d0            ;size: from node to end of string
  210.     move.l    a0,a1
  211.     move.l    4.w,a6
  212.     jsr    -210(a6)        ;FreeMem()
  213.     movem.l    (sp)+,d0-a6
  214.     rts
  215.  
  216.     ENDIF
  217. ;------------------
  218.  
  219.  
  220.  
  221.  
  222. ;------------------------------------------------------------------------------
  223. *
  224. * AddHeadLVNode    Add a listview node at the head of the list.
  225. *
  226. * INPUT:    a0    List.
  227. *        a1    Node.
  228. *        a2    WindowKey.
  229. *        a3    Gadget.
  230. *
  231. ;------------------------------------------------------------------------------
  232.  
  233. ;------------------
  234.     IFD    xxx_AddHeadLVNode
  235. AddHeadLVNode:
  236.  
  237. ;------------------
  238. ; Start.
  239. ;
  240. \start:    movem.l    d0-a6,-(sp)
  241.     move.l    a0,a4
  242.     move.l    a3,a0
  243.     CALL_    RemoveLVLabels
  244.     move.l    a4,a0
  245.     move.l    4.w,a6
  246.     jsr    -240(a6)        ;AddHead()
  247.     move.l    a4,d0
  248.     CALL_    SetLVLabels
  249.     movem.l    (sp)+,d0-a6
  250.     rts
  251.  
  252.     ENDIF
  253. ;------------------
  254.  
  255.  
  256.  
  257.  
  258. ;------------------------------------------------------------------------------
  259. *
  260. * AddTailLVNode    Add a listview node at the tail of the list.
  261. *
  262. * INPUT:    a0    List.
  263. *        a1    Node.
  264. *        a2    WindowKey.
  265. *        a3    Gadget.
  266. *
  267. ;------------------------------------------------------------------------------
  268.  
  269. ;------------------
  270.     IFD    xxx_AddTailLVNode
  271. AddTailLVNode:
  272.  
  273. ;------------------
  274. ; Start.
  275. ;
  276. \start:    movem.l    d0-a6,-(sp)
  277.     move.l    a0,a4
  278.     move.l    a3,a0
  279.     CALL_    RemoveLVLabels
  280.     move.l    a4,a0
  281.     move.l    4.w,a6
  282.     jsr    -246(a6)        ;AddTail()
  283.     move.l    a4,d0
  284.     move.l    a3,a0
  285.     CALL_    SetLVLabels
  286.     movem.l    (sp)+,d0-a6
  287.     rts
  288.  
  289.     ENDIF
  290. ;------------------
  291.  
  292.  
  293.  
  294.  
  295. ;------------------------------------------------------------------------------
  296. *
  297. * RemHeadLVNode    Remove first node of a listview gadget.
  298. *
  299. * INPUT:    a0    List.
  300. *        a1    Node.
  301. *        a2    WindowKey.
  302. *        a3    Gadget.
  303. *
  304. ;------------------------------------------------------------------------------
  305.  
  306. ;------------------
  307.     IFD    xxx_RemHeadLVNode
  308. RemHeadLVNode:
  309.  
  310. ;------------------
  311. ; Start.
  312. ;
  313. \start:    pea    (a1)
  314.     move.l    (a0),a1
  315.     tst.l    (a1)            ;empty?
  316.     beq.s    \done
  317.     CALL_    RemoveLVNode
  318. \done:    move.l    (sp)+,a1
  319.     rts
  320.  
  321.     ENDIF
  322. ;------------------
  323.  
  324.  
  325.  
  326.  
  327. ;------------------------------------------------------------------------------
  328. *
  329. * RemTailLVNode    Remove last node of a listview gadget.
  330. *
  331. * INPUT:    a0    List.
  332. *        a1    Node.
  333. *        a2    WindowKey.
  334. *        a3    Gadget.
  335. *
  336. ;------------------------------------------------------------------------------
  337.  
  338. ;------------------
  339.     IFD    xxx_RemTailLVNode
  340. RemTailLVNode:
  341.  
  342. ;------------------
  343. ; Start.
  344. ;
  345. \start:    pea    (a1)
  346.     move.l    8(a0),a1
  347.     tst.l    4(a1)            ;empty?
  348.     beq.s    \done
  349.     CALL_    RemoveLVNode
  350. \done:    move.l    (sp)+,a1
  351.     rts
  352.  
  353.     ENDIF
  354. ;------------------
  355.  
  356.  
  357.  
  358.  
  359. ;------------------------------------------------------------------------------
  360. *
  361. * RemoveLVNode    Remove a listview node from the gadget.
  362. *
  363. * INPUT:    a0    List.
  364. *        a1    Node.
  365. *        a2    WindowKey.
  366. *        a3    Gadget.
  367. *
  368. ;------------------------------------------------------------------------------
  369.  
  370. ;------------------
  371.     IFD    xxx_RemoveLVNode
  372. RemoveLVNode:
  373.  
  374. ;------------------
  375. ; Start.
  376. ;
  377. \start:    movem.l    d0-a6,-(sp)
  378.     move.l    a0,a4
  379.     move.l    a3,a0
  380.     CALL_    RemoveLVLabels
  381.     move.l    4.w,a6
  382.     jsr    -252(a6)        ;Remove()
  383.     exg.l    a4,d0
  384.     move.l    a3,a0
  385.     CALL_    SetLVLabels
  386.     movem.l    (sp)+,d0-a6
  387.     rts
  388.  
  389.     ENDIF
  390. ;------------------
  391.  
  392.  
  393.  
  394.  
  395.  
  396. ;--------------------------------------------------------------------
  397. *
  398. * ActivateGadget    Activate a gadget.
  399. *
  400. * INPUT:    a0    Gadget.
  401. *        a2    WindowKey.
  402. *
  403. ;--------------------------------------------------------------------
  404.  
  405. ;------------------
  406.  
  407.     IFD    xxx_ActivateGadget
  408. ActivateGadget:
  409.     movem.l    d0-a6,-(sp)
  410.     move.l    (a2),a1
  411.     suba.l    a2,a2
  412.     move.l    gtf_intbase(pc),a6
  413.     jsr    -462(a6)        ;ActivateGadget()
  414.     movem.l    (sp)+,d0-a6
  415.     rts
  416.  
  417.     ENDIF
  418. ;------------------
  419.  
  420.  
  421.  
  422.  
  423. ;--------------------------------------------------------------------
  424. *
  425. * OnMenu    Activate or deactivate menu strip, title, item or subitem.
  426. * OffMenu
  427. *
  428. * INPUT:    d0    *_mn ID number of object.
  429. *        a2    WindowKey.
  430. *
  431. ;--------------------------------------------------------------------
  432.  
  433. ;------------------
  434.  
  435.     IFD    xxx_OnMenu
  436. OnMenu:    movem.l    d0-a6,-(sp)
  437.     move.l    (a2),a0
  438.     move.l    gtf_intbase(pc),a6
  439.     jsr    -192(a6)        ;OnMenu()
  440.     movem.l    (sp)+,d0-a6
  441.     rts
  442.  
  443.     ENDIF
  444. ;------------------
  445.  
  446.     IFD    xxx_OffMenu
  447. OffMenu:
  448.     movem.l    d0-a6,-(sp)
  449.     move.l    (a2),a0
  450.     move.l    gtf_intbase(pc),a6
  451.     jsr    -180(a6)        ;OffMenu()
  452.     movem.l    (sp)+,d0-a6
  453.     rts
  454.  
  455.     ENDIF
  456. ;------------------
  457.  
  458.  
  459.  
  460.  
  461. ;--------------------------------------------------------------------
  462. *
  463. * Different Gadget modification routines.
  464. *
  465. * INPUT:    a0    Gadget.
  466. *        d0    Tag data.
  467. *        a2    WindowKey.
  468. *
  469. * RESULT:    d1    Tag number.
  470. *
  471. ;--------------------------------------------------------------------
  472.  
  473. ;------------------
  474.  
  475.     IFD    xxx_EnableGadget
  476. EnableGadget:
  477. xxx_SetGadgetTag    SET    1
  478.     move.l    #GA_Disabled,d1
  479.     moveq    #0,d0
  480.     bra    SetGadgetTag
  481.     ENDIF
  482.  
  483.  
  484.     IFD    xxx_DisableGadget
  485. DisableGadget:
  486. xxx_SetGadgetTag    SET    1
  487.     move.l    #GA_Disabled,d1
  488.     moveq    #-1,d0
  489.     bra    SetGadgetTag
  490.     ENDIF
  491.  
  492.  
  493.     IFD    xxx_RemoveLVLabels
  494. RemoveLVLabels:
  495. xxx_SetGadgetTag    SET    1
  496.     move.l    #GTLV_Labels,d1
  497.     moveq    #-1,d0
  498.     bra    SetGadgetTag
  499.     ENDIF
  500.  
  501.  
  502.     IFD    xxx_ChangeLVLabels
  503. ChangeLVLabels:
  504. xxx_SetLVLabels        SET    1
  505.     move.l    d0,-(sp)
  506.     CALL_    RemoveLVLabels
  507.     move.l    (sp)+,d0
  508.     ENDIF
  509.  
  510.  
  511.     IFD    xxx_SetLVLabels
  512. SetLVLabels:
  513. xxx_SetGadgetTag    SET    1
  514.     move.l    #GTLV_Labels,d1
  515.     bra    SetGadgetTag
  516.     ENDIF
  517.  
  518.  
  519.     IFD    xxx_SetCYActive
  520. SetCYActive:
  521. xxx_SetGadgetTag    SET    1
  522.     move.l    #GTCY_Active,d1
  523.     bra    SetGadgetTag
  524.     ENDIF
  525.     
  526.  
  527.     IFD    xxx_GetLVLabel
  528. GetLVLabel:
  529.     movem.l    d1/a0,-(sp)
  530.     move.w    d0,d1
  531.     move.l    (a0),d0
  532.  
  533. \loop:    move.l    d0,a0
  534.     move.l    (a0),d0
  535.     beq.s    \no
  536.     subq.w    #1,d1
  537.     bhs.s    \loop
  538.     move.l    a0,d0
  539.  
  540. \no:    tst.l    d0
  541.     movem.l    (sp)+,d1/a0
  542.     rts
  543.     ENDIF
  544.  
  545.  
  546. ;------------------
  547.  
  548.  
  549.  
  550.  
  551.  
  552. ;--------------------------------------------------------------------
  553. *
  554. * SetGadgetTag    Call GT_SetGadgetAttrs with one tag.
  555. *
  556. * INPUT:    a0    Gadget
  557. *        d0    Tag data
  558. *        d1    Tag Number
  559. *        a2    WindowKey.
  560. *
  561. ;--------------------------------------------------------------------
  562.  
  563. ;------------------
  564.     IFD    xxx_SetGadgetTag
  565. SetGadgetTag:
  566. xxx_gtf_tagspace    SET    1
  567.  
  568. ;------------------
  569. ; Do!
  570. ;
  571. \do:    movem.l    d0-a6,-(sp)
  572.     move.l    gfw_window(a2),a1
  573.     suba.l    a2,a2
  574.     lea    gtf_tagspace+12(pc),a3
  575.     clr.l    -(a3)
  576.     move.l    d0,-(a3)
  577.     move.l    d1,-(a3)
  578.     move.l    gtf_gadtoolsbase(pc),a6
  579.     jsr    -42(a6)            ;GT_SetGadgetAttrsA()
  580.     movem.l    (sp)+,d0-a6
  581.     rts
  582.  
  583.     ENDIF
  584. ;------------------
  585.  
  586.  
  587.  
  588.  
  589. ;--------------------------------------------------------------------
  590. *
  591. * FindLVNode    Find Listview node.
  592. * FindLVNodeMsg    Find Listview node that is stated in gfw_msgcode.
  593. *
  594. * INPUT:    a0    List.
  595. *        d0    Number.
  596. *        a2    WindowKey (only for FindLVNodeMsg).
  597. *
  598. * RESULT:    d0    Node or 0.
  599. *        a0    Same as d0.
  600. *        ccr    On d0.
  601. *
  602. ;--------------------------------------------------------------------
  603.  
  604. ;------------------
  605.     IFD    xxx_FindLVNodeMsg
  606.     move.w    gfw_msgcode(a2),d0
  607. xxFindLVNode    SET    1
  608.  
  609.     ENDC
  610.  
  611. ;------------------
  612.     IFD    xxx_FindLVNode
  613. FindLVNode:
  614.  
  615. ;------------------
  616. ; Do!
  617. ;
  618. \do:    move.l    (a0),a0
  619.  
  620. \loop:    tst.l    (a0)
  621.     beq.s    \notfound
  622.     tst.w    d0
  623.     beq.s    \found
  624.     subq.w    #1,d0
  625.     move.l    (a0),a0
  626.     bra.s    \loop
  627.  
  628. \found:    move.l    a0,d0
  629.     rts
  630.  
  631. \notfound:
  632.     moveq    #0,d0
  633.     rts
  634.  
  635.     ENDC
  636.  
  637.  
  638. ;--------------------------------------------------------------------
  639. *
  640. * Historyfunction for Stringgadgets.
  641. *
  642. * You'll need to declare this with 'NEED_ StringHistoryHookFunction'
  643. *
  644. ;--------------------------------------------------------------------
  645.  
  646. ;------------------
  647.     IFD    xxx_StringHistoryHookFunction
  648.  
  649.     rsreset
  650. gtfh_buffer    rs.l    1
  651. gtfh_buflen    rs.l    1
  652. gtfh_bufusage    rs.l    1
  653. gtfh_start    rs.l    1
  654. gtfh_counter    rs.l    1
  655. gtfh_current    rs.l    1
  656. gtfh_SIZEOF    rsval
  657.  
  658. ;
  659. ; HistoryHook_    StringHistStruct
  660. ;
  661. HistoryHook_    MACRO
  662.     dc.l    0,0
  663.     dc.l    StringHistoryHookFunction
  664.     dc.l    0
  665.     dc.l    \1
  666.     ENDM
  667.  
  668.  
  669. ;
  670. ; StringHistoryStruct_    Buffer,BufferSize
  671. ;
  672. StringHistoryStruct_    MACRO
  673.     dc.l    \1
  674.     dc.l    \2
  675.     dc.l    0,0,0,0
  676.     ENDM
  677.  
  678.  
  679. StringHistoryHookFunction:
  680.  
  681. ;------------------
  682. ; Hook.
  683. ;
  684. ;    A0 - pointer to hook itself
  685. ;    A1 - pointer to parameter packet ("message")
  686. ;    A2 - Hook specific address data ("object," e.g, gadget )
  687. ;
  688. \start:    moveq    #0,d0
  689.     cmp.l    #SGH_KEY,(a1)
  690.     bne.s    \done
  691.     movem.l    d3/a3/a4,-(sp)
  692.     move.l    16(a0),a3
  693.     move.l    sgw_Actions(a2),d3
  694.     btst    #SGAB_END,d3
  695.     bne.s    \remember
  696.     move.l    sgw_IEvent(a2),a4
  697.     cmp.b    #$4c,7(a4)
  698.     beq.s    \prev    
  699.     cmp.b    #$4d,7(a4)
  700.     beq.s    \next
  701. \no:    movem.l    (sp)+,d3/a3/a4
  702. \done:    rts
  703.  
  704. \remember:
  705.     bsr.s    \addtohist
  706. \do:    moveq    #-1,d0
  707.     bra.s    \no
  708.  
  709. \prev:    bsr    \historyrew
  710.     bra.s    \do
  711. \next:    bsr    \historyfwd
  712.     bra.s    \do
  713.  
  714.  
  715. ;------------------
  716. ; Add to history buffer
  717. ;
  718. ;    a3:    History Info Block.
  719. ;    a2:    SGWork.
  720. ;
  721. \addtohist:
  722.     movem.l    d0/d1/d7/a0/a1/a4/a5,-(sp)
  723.     move.l    gtfh_buffer(a3),a4    ;start of buffer
  724.     move.l    a4,a5
  725.     move.l    gtfh_buflen(a3),d7    ;length of buffer
  726.     add.l    d7,a5            ;end of buffer
  727.     moveq    #0,d0
  728.     move.w    sgw_NumChars(a2),d0
  729.     beq.s    \fin
  730.     move.w    #254,d1
  731.     cmp.w    d1,d0
  732.     bls.s    1$
  733.     move.w    d1,d0            ;limit to 254+1 (for len)
  734. 1$:    move.l    gtfh_bufusage(a3),d1
  735.     add.l    d0,d1
  736.     addq.l    #1,d1
  737.     cmp.l    d7,d1
  738.     bls.s    \norem
  739.     move.l    a4,a0            ;free last entry and try again
  740.     add.l    gtfh_start(a3),a0
  741.     moveq    #0,d1
  742.     move.b    (a0),d1
  743.     add.l    d1,a0
  744.     bsr.s    \historylimit
  745.     sub.l    a4,a0
  746.     move.l    a0,gtfh_start(a3)
  747.     sub.l    d1,gtfh_bufusage(a3)
  748.     subq.l    #1,gtfh_counter(a3)
  749.     bra.s    1$
  750.  
  751. \norem:    addq.l    #1,gtfh_counter(a3)
  752.     move.l    a4,a0
  753.     add.l    gtfh_bufusage(a3),a0
  754.     add.l    gtfh_start(a3),a0
  755.     move.l    d1,gtfh_bufusage(a3)
  756.  
  757.     bsr.s    \historylimit
  758.     move.b    d0,(a0)
  759.     addq.b    #1,(a0)+
  760.     move.l    sgw_WorkBuffer(a2),a1
  761. \loop:    bsr.s    \historylimit
  762.     move.b    (a1)+,(a0)+
  763.     subq.b    #1,d0
  764.     bne.s    \loop
  765.  
  766. \fin:    clr.l    gtfh_current(a3)
  767.     movem.l    (sp)+,d0/d1/d7/a0/a1/a4/a5
  768.     rts
  769.  
  770. \historylimit:
  771.     cmp.l    a4,a0
  772.     bhs.s    \nl1
  773.     add.l    d7,a0
  774. \nl1:    cmp.l    a5,a0
  775.     blo.s    \nl2
  776.     sub.l    d7,a0
  777. \nl2:    rts
  778.  
  779.  
  780.  
  781. ;------------------
  782. ; Go one forth in command history.
  783. ; If nothing to go forth, clear line.
  784. ;
  785. \historyfwd:
  786.     tst.l    gtfh_current(a3)
  787.     beq.s    \gethistory
  788.     subq.l    #1,gtfh_current(a3)
  789.     bra.s    \gethistory
  790.  
  791. \historyrew:
  792.     addq.l    #1,gtfh_current(a3)
  793.  
  794. \gethistory:
  795.     movem.l    d0/d1/d7/a4/a5/a1,-(sp)
  796.     move.l    gtfh_buffer(a3),a4    ;start of buffer
  797.     move.l    a4,a5
  798.     move.l    gtfh_buflen(a3),d7    ;length of buffer
  799.     add.l    d7,a5            ;end of buffer
  800.  
  801.     move.l    sgw_WorkBuffer(a2),a1
  802.     move.l    gtfh_current(a3),d1
  803.     beq.s    \cls
  804.     move.l    gtfh_counter(a3),d0
  805.     beq.s    \cls
  806.     cmp.l    d0,d1
  807.     bls.s    11$
  808.     move.l    d0,d1
  809. 11$:    move.l    d1,gtfh_current(a3)
  810.     move.l    a4,a0
  811.     add.l    gtfh_start(a3),a0
  812.     sub.l    d1,d0
  813.     beq.s    \got
  814. \loop3:    moveq    #0,d1
  815.     move.b    (a0),d1
  816.     add.l    d1,a0
  817.     bsr.s    \historylimit
  818.     subq.l    #1,d0
  819.     bne.s    \loop3
  820.  
  821. \got:    moveq    #0,d1
  822.     move.b    (a0)+,d1
  823.     subq.l    #1,d1
  824.     clr.w    sgw_BufferPos(a2)
  825.     move.w    d1,sgw_NumChars(a2)
  826.     beq.s    \done2
  827.  
  828. \loop2:    bsr.s    \historylimit
  829.     move.b    (a0)+,(a1)+
  830.     subq.w    #1,d1
  831.     bne.s    \loop2
  832.  
  833. \done2:    clr.b    (a1)
  834.     movem.l    (sp)+,d0/d1/d7/a4/a5/a1
  835.     rts
  836.  
  837. \cls:    clr.w    sgw_NumChars(a2)
  838.     clr.w    sgw_BufferPos(a2)
  839.     bra.s    \done2
  840.  
  841.     ENDC
  842.  
  843.  
  844. ;--------------------------------------------------------------------
  845.  
  846. ;------------------
  847.     endif
  848.  
  849.     end
  850.